﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PropertyManagement.Core.DataAccess;
using PropertyManagement.Core.Model;

namespace PropertyManagement.Core {
    public class FeeBillManage {
        public EmptyFeeManagementBill CreationEmptyManagementBill(BillType type, HouseOwner owner) {
            var billMonthyMapping = new BillMonthyMapping {
                BillMonth = new DateTime(DateTime.Now.AddDays(3).Year, DateTime.Now.AddDays(3).Month, 1),
                HouseOwnerID = owner.HouseOwnerID,
                BillType = type
            };
            if (!BillMonthyMappingDataAccess.ExistsByPKs(billMonthyMapping)) {
                var unitPrice = 0m;

                var unitEntity = FeeUnitPriceManageDataAccess.GetUnitByBillType(type);
                if (unitEntity != null) {
                    unitPrice = unitEntity.UnitPrice;
                }
                return new EmptyFeeManagementBill {
                    ApartmentName = owner.ApartmentName,
                    BillEffectiveDate = DateTime.Now.AddDays(3),
                    ExpireDate = DateTime.Now.AddDays(10),
                    BillType = type,
                    UnitPrice = unitPrice,
                    SpaceArea = owner.SpaceArea,
                    CallableMoney = unitPrice*owner.SpaceArea,
                    HouseCode = owner.HouseCode,
                    HouseOwnerID = owner.HouseOwnerID,
                    OwnerName = owner.OwnerName,

                };
            }
            else {
                return null;
            }

           
        }

        public EmptyFeeInstrumentBill CreationEmptyFeeInstrumentBill(BillType type, HouseOwner owner) {
              var billMonthyMapping = new BillMonthyMapping {
                BillMonth = new DateTime(DateTime.Now.AddDays(3).Year, DateTime.Now.AddDays(3).Month, 1),
                HouseOwnerID = owner.HouseOwnerID,
                BillType = type
            };
            if (!BillMonthyMappingDataAccess.ExistsByPKs(billMonthyMapping)) {
                var unitPrice = 0m;
                var instrumentType = InstrumentType.Water;
                var unitEntity = FeeUnitPriceManageDataAccess.GetUnitByBillType(type);
                if (unitEntity != null) {
                    unitPrice = unitEntity.UnitPrice;
                }
                if (type == BillType.WaterFee) {
                    instrumentType = InstrumentType.Water;
                }
                else if (type == BillType.ElectricFee) {
                    instrumentType = InstrumentType.Electricity;
                }
                else if (type == BillType.GasFee) {
                    instrumentType = InstrumentType.Gas;
                }
                else {
                    throw new IndexOutOfRangeException("账单类型错误");
                }
                var lastInstrumentCord = InstrumentRecordDataAccess.GetLastRecord(owner.HouseOwnerID, instrumentType);

                var bill = new EmptyFeeInstrumentBill {
                    ApartmentName = owner.ApartmentName,
                    BillEffectiveDate = DateTime.Now.AddDays(3),
                    ExpireDate = DateTime.Now.AddDays(10),
                    BillType = type,
                    UnitPrice = unitPrice,
                    HouseCode = owner.HouseCode,
                    HouseOwnerID = owner.HouseOwnerID,
                    OwnerName = owner.OwnerName,
                    InstrumentType = instrumentType,
                    InstrumentName = owner.HouseCode + "_" + InstrumentTypeHelper.GetInstrumentTypeName(instrumentType)
                };
                if (lastInstrumentCord == null) {
                    bill.LastDate = DateTime.MinValue;
                    bill.CurrentDate = DateTime.MinValue;
                }
                else {
                    bill.LastDate = lastInstrumentCord.CurrentDate;
                    bill.LastValue = lastInstrumentCord.CurrentValue;
                    bill.CurrentDate = lastInstrumentCord.CurrentDate.AddMonths(1);
                }
                return bill;
            }
            else {
                return null;
            }
        }

        public void SaveManagementBills(IEnumerable<EmptyFeeManagementBill> bills) {
           var managementBills =  bills.Select(b => new PropertyManagementFeeBill {
                HouseID = b.HouseOwnerID,
                BillType = b.BillType,
                CallableMoney = b.CallableMoney,
                CreationDate = DateTime.Now,
                CreationUserID = StaticProvider.Instance.CurrentLoginedUser.SystemUserID,
                LastUpdate = DateTime.Now,
                LastActionUserID = StaticProvider.Instance.CurrentLoginedUser.SystemUserID,
                EffectiveDate = b.BillEffectiveDate.Date,
                ExpireDate = b.ExpireDate.Date,
                PaidDate = DateTime.MaxValue,
            });
            //ForEach(pb => {
            //    if (!PropertyManagementFeeBillDataAccess.ExistsByPKs(pb)) {
            //        PropertyManagementFeeBillDataAccess.Add(pb);
            //    }
            //});

            foreach (var b in managementBills) {
                if (!PropertyManagementFeeBillDataAccess.ExistsByPKs(b)) {
                    PropertyManagementFeeBillDataAccess.Add(b);
                }
                var billMonthyMapping = new BillMonthyMapping {
                    BillMonth = new DateTime(b.EffectiveDate.Year, b.EffectiveDate.Month, 1),
                    FeeBillID = b.PropertyManagementFeeBillID,
                    HouseOwnerID = b.HouseID,
                    BillType = b.BillType
                };
                SaveBillMonthyMapping(billMonthyMapping);
            }

        }

        private void SaveBillMonthyMapping(BillMonthyMapping billMonthyMapping) {
            billMonthyMapping.CreationDate = billMonthyMapping.LastUpdate = DateTime.Now;
            billMonthyMapping.CreationUserID =
                billMonthyMapping.LastActionUserID = StaticProvider.Instance.CurrentLoginedUser.SystemUserID;
            if (!BillMonthyMappingDataAccess.ExistsByPKs(billMonthyMapping)) {
                BillMonthyMappingDataAccess.Add(billMonthyMapping);
            }
        }


        public void SaveInstrumentBills(IEnumerable<EmptyFeeInstrumentBill> bills) {
            bills.ToList().ForEach(b => {
                var pb = new PropertyManagementFeeBill {
                    HouseID = b.HouseOwnerID,
                    BillType = b.BillType,
                    CallableMoney = b.CallableMoney,
                    CreationDate = DateTime.Now,
                    CreationUserID = StaticProvider.Instance.CurrentLoginedUser.SystemUserID,
                    LastUpdate = DateTime.Now,
                    LastActionUserID = StaticProvider.Instance.CurrentLoginedUser.SystemUserID,
                    EffectiveDate = b.BillEffectiveDate.Date,
                    ExpireDate = b.ExpireDate.Date,
                    PaidDate = DateTime.MaxValue,
                };
                var instrumentRecord = new InstrumentRecord {
                    HouseID = b.HouseOwnerID,
                    CreationDate = DateTime.Today,
                    CreationUserID = StaticProvider.Instance.CurrentLoginedUser.SystemUserID,
                    LastUpdate = DateTime.Now,
                    LastActionUserID = StaticProvider.Instance.CurrentLoginedUser.SystemUserID,
                    LastDate = b.LastDate!=null?b.LastDate.Value:DateTime.Today,
                    LastValue = b.LastValue,
                    CurrentDate = b.CurrentDate != null ? b.CurrentDate.Value : DateTime.Today,
                    CurrentValue = b.CurrentValue,
                    InstrumentType = b.InstrumentType
                    
                };
                if (!PropertyManagementFeeBillDataAccess.ExistsByPKs(pb)) {
                    PropertyManagementFeeBillDataAccess.Add(pb);
                }
                if (!InstrumentRecordDataAccess.ExistsByPKs(instrumentRecord)) {
                    InstrumentRecordDataAccess.Add(instrumentRecord);
                }
                MappingDataAccess.AddBillInstrumentMapping(pb.PropertyManagementFeeBillID,
                                                           instrumentRecord.InstrumentRecordID);
                var billMonthyMapping = new BillMonthyMapping {
                    BillMonth = new DateTime(pb.EffectiveDate.Year, pb.EffectiveDate.Month, 1),
                    FeeBillID = pb.PropertyManagementFeeBillID,
                    HouseOwnerID = pb.HouseID,
                    BillType = b.BillType
                };
                SaveBillMonthyMapping(billMonthyMapping);
            });
        }

        public PropertyManagementFeeBill GetBillById(int billId) {
            return PropertyManagementFeeBillDataAccess.GetById(billId);
        }

        public void PaidBills(IEnumerable<PropertyManagementFeeBill> bills) {
            foreach (var b in bills) {
                b.LastUpdate = DateTime.Now;
                b.LastActionUserID = StaticProvider.Instance.CurrentLoginedUser.SystemUserID;

                b.IsCompletePaid = true;
                PropertyManagementFeeBillDataAccess.Update(b);
            }
        }
    }
}
